﻿using System;
using System.Linq;
using System.Text;
using System.Collections.Generic;

namespace FoundationLib.Common.Collections
{
	/// <summary>
	/// Represents a wrapper to an underlying <see cref="IList{T}"/> instance. It can be used as a 
	/// basis for user-defined collection and mapped by using NHibernate's &lt;component&gt; elements.
	/// The difference between the <see cref="BoxedCollection{T}"/> and this type is that 
	/// <see cref="AggregateCollection{TRef, TItem}"/> contains a back-reference to the set container 
	/// of type <typeparamref name="TRef"/>.
	/// </summary>
	/// <typeparam name="TRef">The type containing this boxed set</typeparam>
	/// <typeparam name="TItem">The type of the elements in the underlying set</typeparam>
	public class AggregateCollection<TRef, TItem> : BoxedCollection<TItem>
	{
		/// <summary>
		/// The container of the set elements
		/// </summary>
		private TRef container;


		/// <summary>
		/// Gets or sets the set element container.
		/// </summary>
		/// <remarks>The access to the setter is protected.</remarks>
		public TRef Container
		{
			get { return container; }
			protected set { container = value; }
		}

		/// <summary>
		/// Creates a new <see cref="AggregateCollection&lt;TRef, TItem&gt;"/> instance.
		/// </summary>
		public AggregateCollection()
			: base()
		{
		}

		/// <summary>
		/// Creates a new <see cref="AggregateCollection&lt;TRef, TItem&gt;"/> instance.
		/// </summary>
		/// <param name="container">The back-reference to the object containing this boxed set</param>
		public AggregateCollection(TRef container)
			: this()
		{
			this.container = container;
		}

		/// <summary>
		/// Creates a new <see cref="AggregateCollection&lt;TRef, TItem&gt;"/> instance.
		/// </summary>
		/// <param name="container">The back-reference of the object containing this boxed set</param>
		/// <param name="elements">The set items</param>
		public AggregateCollection(TRef container, IList<TItem> elements)
			: this(container)
		{
			this.Elements = elements;
		}
	}
}
